﻿using System;
using System.Collections.Generic;
using System.Linq;
using Missbot.Common;
using Missbot.Core.Base;
using Missbot.Core.SyntaxChecker;
using Dolany.UtilityTool;

namespace Missbot.AIModule.Base
{
    /// <summary>
    /// AI模块基类
    /// </summary>
    public abstract class IAIModule : ISingleton
    {
        /// <summary>
        /// 模块名称
        /// </summary>
        public abstract string Name { get; }

        /// <summary>
        /// 优先级
        /// </summary>
        public virtual AIPriority Priority => AIPriority.Normal;

        /// <summary>
        /// 父级标签
        /// </summary>
        public virtual string ParentTag => null;

        /// <summary>
        /// 所有的入口单元
        /// </summary>
        public readonly List<ModEnterUnit> EnterUnits = new();

        #region Svcs

        public SyntaxCheckerSvc SyntaxCheckerSvc { get; set; }
        public ILogSvc ILogSvc { get; set; }

        #endregion

        /// <summary>
        /// 初始化
        /// </summary>
        public virtual void Initialization()
        {
            var t = GetType();
            // 循环查找解析所有入口单元
            foreach (var method in t.GetMethods())
            {
                foreach (ModuleEnterAttribute attr in method.GetCustomAttributes(typeof(ModuleEnterAttribute), false))
                {
                    // 使用空格分隔同义的命令
                    foreach (var command in attr.Command.Split(" "))
                    {
                        var attrClone = attr.Clone(); // 因为可能设置不同的Command，所以要使用克隆的对象
                        attrClone.Command = command;
                        attrClone.ID = $"{t.Name}.{method.Name}";
                        EnterUnits.Add(new ModEnterUnit
                        {
                            Attr = attrClone,
                            Method = method,
                            SenderModule = this,
                            Params = method.GetParameters()
                                           .Where(pa => pa.ParameterType != typeof(InboxSession))
                                           .ToArray()
                        });
                        ILogSvc.Log($"{command}（{method.Name}） Loaded.");
                    }
                }
            }
        }

        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        public bool OnInbox(InboxSession session)
        {
            // 禁止响应机器人的消息
            return session.User is { IsBot: true } || OnInboxImpl(session);
        }

        /// <summary>
        /// 处理消息功能实现部分
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        protected virtual bool OnInboxImpl(InboxSession session)
        {
            try
            {
                if (string.IsNullOrEmpty(session.Text))
                {
                    return false;
                }

                var command = session.Text.Split(" ").FirstOrDefault(); // 先解析出入口命令
                // 仅匹配命令相同且支持当前通道的入口单元
                var eus = EnterUnits.Where(enterUnit => enterUnit.Attr.Command == command && enterUnit.Attr.ChannelType.HasFlag(session.Channel.BindingType));
                foreach (var unit in eus)
                {
                    // 参数校验及解析
                    var (syntaxResult, @params) = SyntaxCheckerSvc.SyntaxCheck(unit.Params, session.Text);
                    if (!syntaxResult)
                    {
                        continue;
                    } 

                    unit.Invoke(@params, session);
                    return true;
                }

                return false;
            }
            catch (Exception e)
            {
                ILogSvc.LogError(e);
                return false;
            }
        }
    }
}